/**
 * @file
 * Access Reference Map module header.
 * <P>
 * The Access Reference Map is used to map from a set of internal
 * direct object references to a set of indirect references that are safe to
 * disclose publicly. This can be used to help protect database keys,
 * filenames, and other types of direct object references. As a rule, developers
 * should not expose their direct object references as it enables attackers to
 * attempt to manipulate them.
 * <P>
 * Indirect references are handled as strings, to facilitate their use in GUI controls
 * or service messages.
 * <P>
 * Note that in addition to defeating all forms of parameter tampering attacks,
 * there is a side benefit of the Access Reference Map. Using random strings as indirect object
 * references, as opposed to simple integers makes it impossible for an attacker to
 * guess valid identifiers. So if per-user Access Reference Maps are used, then request
 * forgery attacks will also be prevented.
 *
 * @code
 *	char *value = "This is a direct object reference";
 *	esapi_put_reference(esapi_get_unique_reference(value), value);
 * @endcode
 *
 * @since January 30, 2011
 */

#include <stdbool.h>

#include "crypto.h"
#include "uthash.h"

#ifndef _ACCESS_REF_H
#define _ACCESS_REF_H

/**
 *  The fixed length of an access reference map key, generated by get_unique_reference().
 */
#define KEY_LEN	 7

/**
 * The maximum length of an access reference map value.
 *
 * @todo Change to support dynamically sized values.
 */
#define VAL_LEN 64

/**
 * A hashable key-value pair for an access reference map. Both key-to-value and value-to-key
 * lookups are supported.
 */
struct Map_t {
	char key[KEY_LEN + 1];
	char val[VAL_LEN + 1];
	UT_hash_handle hh_k; // handle for first hash table - key
	UT_hash_handle hh_v; // handle for second hash table - value
};

typedef struct Map_t map_t;

extern map_t *v_map;
extern map_t *k_map;

/**
 * Adds an entry to the map.  The indirect reference should be obtained by calling
 * esapi_get_unique_reference().
 * @param A character array containing an indirect object reference
 * @param A character array containing a direct object reference
 * @see esapi_get_unique_reference()
 */
extern bool esapi_put_reference(const char *, const char *);

/**
 * Returns the indirect object reference for the given direct object reference.
 * @param A character array containing a direct object reference
 * @return A character array containing an indirect object reference
 */
extern char *esapi_get_indirect_reference(const char *);

/**
 * Returns the direct object reference (original value) for the given indirect object reference.
 * @param A character array containing an indirect object reference
 * @return A character array containing a direct object reference
 */
extern char *esapi_get_direct_reference(const char *);

/**
 * Removes the direct object reference from the map.
 * @param A character array containing a direct object reference
 */
extern bool esapi_remove_direct_reference(const char *);

/**
 * Removes the indirect object reference from the map.
 * @param A character array containing an indirect object reference
 */
extern bool esapi_remove_indirect_reference(const char *);

/**
 * Return a unique token string suitable for use as an indirect reference.
 * @return  A character array containing an indirect object reference
 */
extern char *esapi_get_unique_reference();

#endif

